#if !defined(MOUSECTRACERMANGERIMPL1_H_INCLUDED)
#define MOUSECTRACERMANGERIMPL1_H_INCLUDED

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include "MouseTracerManager.h"

#pragma warning(push)

#include <yvals.h>				// warning numbers get enabled in yvals.h

#pragma warning(disable: 4018)
#pragma warning(disable: 4100)
#pragma warning(disable: 4245)
#pragma warning(disable: 4512)
#pragma warning(disable: 4663)
#pragma warning(disable: 4710)
#pragma warning(disable: 4786)

#include <map>
#include <algorithm>

// forward reference;
template<class T>
class CMouseTracer;

/**
 *	CMouseTracerManager11 class
 *
 *	Type 1 : install hooks on all the exsiting windows then setup application hook to monitor windows creation/destruction activity,
 *				each window will have its own hook installed
 *
 */
class CMouseTracerManagerImpl1
{
	friend class CMouseTracerManager<CMouseTracerManagerImpl1>;

public:
	static BOOL SetupMouseTracer(HINSTANCE hMod = NULL) { return CMouseTracerManagerImpl1::Instance().Setup(hMod); }
	static void RemoveMouseTracer() { CMouseTracerManagerImpl1::Instance().Remove(); }

public:
	CMouseTracerManagerImpl1();
	virtual ~CMouseTracerManagerImpl1();
	
protected:
	static CMouseTracerManagerImpl1 &Instance() { static CMouseTracerManagerImpl1 instance; return instance; }

private:
	BOOL Setup(HINSTANCE hMod = NULL);
	void Remove();

	static BOOL CALLBACK SetupExistingWindowsProc(HWND hWnd, LPARAM lParam);
	static LRESULT CALLBACK CallWndRetProc(int nCode, WPARAM wParam, LPARAM lParam);

private:
    static HHOOK m_hHook;
	static struct TRACERMAP : public std::map<LPVOID, LPVOID>
	{
		// functor to unhook the window and delete the hook object from memory
		struct UnhookAndDelete_t
		{
			// type determined automatically
			template<typename T>
			void operator() (T &rPair)
			{
				UnhookAndDelete((HWND)rPair.first, rPair.second);
			}
			
			void UnhookAndDelete(HWND hWnd, LPVOID pPtr);
		};
	} m_mouseTracers;

};

#pragma warning(pop)

#endif // !defined(MOUSETRACERMANGERIMPL1_H_INCLUDED)
